package name.cyrax.red.jpv.impl.funcs.contexts;

import java.util.ArrayList;
import java.util.List;

import name.cyrax.red.jpv.api.adapters.CalculationContext;
import name.cyrax.red.jpv.api.adapters.NumericAccessor;
import name.cyrax.red.jpv.api.adapters.NumericAdapter;
import name.cyrax.red.jpv.api.adapters.PrepareAdapter;
import name.cyrax.red.jpv.api.funcs.InvocableAdapter;
import name.cyrax.red.jpv.api.funcs.InvocationContext;

public class SimpleAnalyzeInvocationContext implements InvocationContext
{
	private final List<PrepareAdapter> preparables = new ArrayList<>(32);
	
	public NumericAdapter collect(InvocableAdapter adapter) {
		final NumericAdapter root = adapter.access(this, NumericAccessor.GET_ADAPTER);
		collect(root);
		return root;
	}
	private void collect(NumericAdapter adapter) {
		int idxParam = 0;
		while (true) {
			NumericAdapter p = adapter.getParam(idxParam);
			if (p == null) break;
			collect(p);
			idxParam++;
		}
		analyzeAdapter(adapter);
	}	
	
	public boolean isOptimizationNeeded() {
		return false;//reusedAdapters > 0;
	}

	public NumericAdapter optimize(InvocableAdapter adapter) {
		throw new UnsupportedOperationException();
	}
	
	protected void analyzeAdapter(NumericAdapter adapter)
	{
		PrepareAdapter p = adapter.prepare();
		if (p != null) {
			preparables.add(p);
		}		
	}

	public PrepareAdapter[] getPrepareAdapters() {
		if (preparables.isEmpty()) return null;
		PrepareAdapter[] result = new PrepareAdapter[preparables.size()];
		int idxResult = 0;
		for (PrepareAdapter p: preparables)
			result[idxResult++] = p;
		return result ;
	}

	@Override public CalculationContext getCalculationContext()
	{
		return CalculationContext.NULL;
	}

	@Override public void beginCalc()
	{
		throw new UnsupportedOperationException();
	}

	@Override public void endCalc()
	{
		throw new UnsupportedOperationException();
	}
}
